Przykad 8.5. Dopasowanie obustronne z uyciem algorytmu Forda-Fulkersona
public class BipariteMatching {

   ArrayList<EdgeInfo> edges;  /* Krawdzie ze zbiorw S i T */
   int ctr = 0;                /* Licznik niepowtarzalnych id. */

   /* Odwzorowania przejcia midzy egzemplarzami problemw */
   HashTable<Object,Integer> map = new HashTable<Object,Integer>();
   HashTable<Integer,Object> reverse = new HashTable<Integer,Object>();

   int srcIndex;    /* Indeks rdowy problemu sieci przepywowej */
   int tgtIndex;    /* Indeks docelowy problemu sieci przepywowej */
   int numVertices; /* Liczba wierzchokw w problemie sieci przepywowej */

   public BipariteMatching (Object[] setS, Object[] setT, Object[][] pairs)
      throws RuntimeException {

      edges = new ArrayList<EdgeInfo>();

      // Zamie pary na odpowiednie wejcie sieci przepywowej.
      // Wszystkie krawdzie maj przepustowo 1.
      for (int i = 0; i < pairs.length; i++) {
         Integer src = map.get(pairs[i][0]);
         Integer tgt = map.get(pairs[i][1]);
         if (src == null) {
            map.put(pairs[i][0]), src = ++ctr);
            reverse.put(src, pairs[i][0]);
         }
         if (tgt == null) {
            map.put(pairs[i][1]), tgt = ++ctr);
            reverse.put(tgt, pairs[i][1]);
         }

         edges.add(new EdgeInfo(src, tgt, 1));
    }

      // Dodaj dodatkowe wierzchoki: "rdowy" i "docelowy"
      srcIndex = 0;
      tgtIndex = setS.length + setT.length+1;
      numVertices = tgtIndex+1;
      for (Object o : setS) {
         edges.add(new EdgeInfo(0, map.get(o), 1));
      }
      for (Object o : setT) {
         edges.add(new EdgeInfo(map.get(o), ctr+1, 1));
      }
   }

   public Iterator<Pair> compute() {
      FlowNetworkArray network = new FlowNetworkArray(numVertices,
                     srcIndex, tgtIndex, edges.iterator());
      FordFulkerson solver = new FordFulkerson (network,
                     new DFS_SearchArray(network));
      solver.compute();

      // Odzyskuj z pierwotnego zbioru edgeInfo; pomijaj krawdzie
      // utworzone do dodanego "rda" i "ujcia". Doczaj do
      // rozwizania tylko wwczas, gdy przepyw == 1
      ArrayList<Pair> pairs = new ArrayList<Pair>();
      for (EdgeInfo ei : edges) {
         if (ei.start != srcIndex && ei.end != tgtIndex) {
            if (ei.getFlow() == 1) {
               pairs.add(new Pair(reverse.get(ei.start), reverse.get(ei.end)));
            }
         }
      }

      return pairs.iterator();
   }
}
